package tablature;

import java.io.Serializable;
import java.util.ArrayList;

/**
 * Class: Measure
 * Description: Holds a list of bar lines and the
 * associated components for each bar line.
 * @author et
 */
public class Measure implements Serializable
{

    public static final String BAR_LINE = "|";

    private ArrayList <String> componentNames;
    private ArrayList <BarLine> barLines;

    private int longestComponentLength;

    private TimeSignature timeSignature;

    /**
     * Constructor for Measure
     * This is never called directly.
     * The application uses the other constructor.
     * @param componentNames - the component names
     * @param measure - the bar lines.
     * @param timeSignature - the current time signature.
     */
    private Measure(ArrayList <String> componentNames, ArrayList <BarLine> barLines, TimeSignature timeSignature, int longestComponentLength)
    {
        this.componentNames = componentNames;
        this.barLines = barLines;
        this.timeSignature = timeSignature;

        this.longestComponentLength = longestComponentLength;
    }

    /**
     * Constructor for Measure
     * @param timeSignature - the current time signature.
     */
    public Measure(TimeSignature timeSignature)
    {
        this(new ArrayList <String> (), new ArrayList<BarLine>(), timeSignature, 0);
    }



    /**
     * Adds a bar line and it's component name to the measure.
     * When it's adding a new bar line, it also checks
     * to see what the longest component name is so it can
     * padd the other components with spaces and ensure all the components
     * line up in the tablature.
     * @param componentName - the component name
     * @param barLine - the bar line.
     */
    public void addBarLine(String componentName, BarLine barLine)
    {
        if (!componentNames.contains(componentName))
        {
            componentNames.add(componentName);
            barLines.add(barLine);

            if (barLine.getName().length() > longestComponentLength)
            {
                longestComponentLength = barLine.getName().length();
            }
        }
    }

    /**
     * Gets a the bar line at a given position.
     * @param pos - the position in the measure.
     * @return the bar line at that position.
     */
    public BarLine getBarLine(int pos)
    {
        return barLines.get(pos);
    }

    public int getBarLinePos(String componentName)
    {
        return componentNames.indexOf(componentName);
    }

    public ArrayList getBarLines()
    {
        return barLines;
    }

    /**
     * Sets the bar line at a given position.
     * @param pos - the position
     * @param barLine - the new bar line.
     */
    public void setBarLine(int pos, BarLine barLine)
    {
        barLines.set(pos, barLine);
    }

    public String getComponentName(int pos)
    {
        return componentNames.get(pos);
    }

    /**
     * Gets the number of bars in the measures
     * @return the numbers of bars in the measure
     */
    public int getNumberOfBars()
    {
        return barLines.size();
    }

    public BarLine getTimingBar()
    {
        return barLines.get(barLines.size() - 1);
    }

    public void setTimingBar(BarLine timingLine)
    {
        barLines.set(barLines.size() - 1, timingLine);
    }

    public TimeSignature getTimeSignature()
    {
        return timeSignature;
    }


    public ArrayList <String> getComponentNames()
    {
        return componentNames;
    }

    public int getLongestComponentLength()
    {
        return longestComponentLength;
    }



    /**
     * Gets a String representation of this measure.
     * @return measureOut - the measure
     */
    public String toString()
    {
        String measureOut = "";
        for (int i = 0; i < barLines.size(); i++)
        {
            String componentName = componentNames.get(i);

            measureOut += getPaddingSpaces(componentName) + componentNames.get(i) + BAR_LINE + barLines.get(i) + BAR_LINE + "\n";
        }

        return measureOut;
    }

    /**
     * Gets the padding spaces for a component name if
     * it's not as long as the longest component name.
     * @param componentName - the component name
     * @return - the spaces needed.
     */
    public String getPaddingSpaces(String componentName)
    {
        String padding = "";

        int difference = longestComponentLength - componentName.length();
        for (int i = 0; i < difference; i++)
        {
            padding += " ";
        }

        return padding;
    }



}
